package cars

import (
	"context"
	"errors"
	"parking-lot-go-push/model"
	"parking-lot-go-push/model/order"
	"parking-lot-go-push/mongodb"
	"time"

	"go.mongodb.org/mongo-driver/bson"
)

type CarsEntryStruct struct {
	Id         int       `gorm:"type:int(11) auto_increment; NOT NULL; primary_key"`
	ParkCode   string    `gorm:"type:varchar(255); COMMENT:'停车场码'"`
	ParkName   string    `gorm:"type:varchar(255); COMMENT:'停车场名称'"`
	CarNumber  string    `gorm:"type:varchar(255); COMMENT:'车牌号'"`
	InTime     time.Time `gorm:"type:datetime; COMMENT:'进入时间'"`
	InPhoto    string    `gorm:"type:varchar(255); COMMENT:'入场图片'"`
	SerialNo   string    `gorm:"type:varchar(255); COMMENT:'进场流水号'"`
	RegionCode string    `gorm:"type:varchar(255); COMMENT:'入场区域编号'"`
	RegionName string    `gorm:"type:varchar(255); COMMENT:'入场区域名称'"`
	CreatedAt  time.Time `gorm:"type:datetime"`
	UpdatedAt  time.Time `gorm:"type:datetime"`
	MemberId   int       `gorm:"type:int(11)"`
	CarNoColor int       `gorm:"type:tinyint(1); COMMENT:'车牌颜色'"`
	MuchId     string    `gorm:"type:varchar(255); COMMENT:'商户号'"`
	OrderNo    string    `gorm:"type:varchar(255)"`
	OrderType  int       `gorm:"type:tinyint(1); COMMENT:'订单类型'"`
	Repeated   int       `gorm:"type:tinyint(1); COMMENT:'重复进场'"`
	PushStatus int       `gorm:"type:tinyint(1); COMMENT:'推送状态'"`
	PushErrNum int       `gorm:"type:tinyint(1); COMMENT:'失败次数'"`
	PushTime   int       `gorm:"type:tinyint(1); COMMENT:'下次推送时间'"`
}

func (c *CarsEntryStruct) TableName() string {
	return "cars_entry"
}

func (c *CarsEntryStruct) PushSuccess(orderNo, inTime, parkCode string, orderType int, abnormal int) error {
	// 开始事务
	tx := model.Db.Begin()

	//更新推送状态
	tx.Model(&CarsEntryStruct{}).Where("order_no", orderNo).Update("push_status", 1)

	//更新订单表
	tx.Model(&order.OrderStruct{}).Where("order_no", orderNo).Updates(map[string]interface{}{
		"status":           1,
		"in_time":          inTime,
		"static_park_code": parkCode,
	})

	//判断表类型
	var updateStruct interface{}
	switch orderType {
	case 1: //小强
		updateStruct = &order.OrderXiaoqiangStruct{}
	case 2: //泊安飞
		updateStruct = &order.OrderParknflyStruct{}
	case 3: //钉钉 (不需要额外更新)
		updateStruct = nil
	default:
		// 未知类型的处理
		tx.Rollback()
		return errors.New("三方表类型不存在")
	}

	if updateStruct != nil {
		//更新三方表
		tx.Model(updateStruct).Where("order_no", orderNo).Updates(map[string]interface{}{
			"status":   1,
			"abnormal": abnormal,
		})
	}

	if tx.Error != nil {
		// 发生错误，回滚事务
		tx.Rollback()

		return tx.Error
	}

	ctx := context.TODO()
	var carsEntryMongoDb mongodb.CarsEntryMongoDbStruct
	model.MongoDb.Collection(carsEntryMongoDb.MongoDBTableName()).DeleteMany(ctx, bson.M{"order_no": orderNo})

	tx.Commit()

	// 检查提交是否出现错误
	if tx.Error != nil {
		return tx.Error
	}
	return nil
}

// 推送失败更新状态
func (c *CarsEntryStruct) PushError(orderNo string, errNum int) error {

	ctx := context.TODO()
	var err error

	//重试时间计算
	lastPushTime := int(time.Now().Unix())
	switch errNum {
	case 3:
		lastPushTime += 3 * 60
	case 4:
		lastPushTime += 5 * 60
	default:
		lastPushTime += 60
	}

	//更新mongdb数据
	var carsEntryMongoDb mongodb.CarsEntryMongoDbStruct
	_, err = model.MongoDb.
		Collection(carsEntryMongoDb.MongoDBTableName()).
		UpdateOne(
			ctx,
			bson.M{"order_no": orderNo},
			bson.M{
				"$set": bson.M{
					"push_err_num": errNum + 1,
					"push_time":    lastPushTime,
				},
			})

	if err != nil {
		return errors.New("更新mongodb失败" + err.Error())
	}

	//更新mysql数据
	err = model.UpdateModelData(
		model.Db,
		c.TableName(),
		map[string]interface{}{
			"order_no": orderNo,
		},
		map[string]interface{}{
			"push_err_num": errNum + 1,
			"push_time":    lastPushTime,
		},
	)

	if err != nil {
		return errors.New("更新mysql失败" + err.Error())
	}

	return nil
}
